"""Global error handling and standardized responses."""

from __future__ import annotations

import logging
import traceback
from typing import Any

from fastapi import HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

from starlette import status

logger = logging.getLogger(__name__)


def format_response(code: int, message: str, data: object | None = None) -> dict[str, Any]:
    """Create a standardized JSON structure used by legacy API utils.

    Note: New endpoints should prefer returning plain Pydantic models
    per RESTful standards. This helper exists to maintain backward
    compatibility for existing utilities.
    """
    return {
        "code": code,
        "message": message,
        "data": data,
    }


async def http_exception_handler(_: Request, exc: HTTPException) -> JSONResponse:
    """
    Handle FastAPI HTTP exceptions.
    Returns standard RESTful error format: {detail: string}
    """
    detail = exc.detail if exc.detail else exc.__class__.__name__
    return JSONResponse(status_code=exc.status_code, content={"detail": detail})


async def validation_exception_handler(_: Request, exc: RequestValidationError) -> JSONResponse:
    """
    Handle Pydantic validation errors.
    Returns standard RESTful error format: {detail: string}
    """
    # Convert validation errors to serializable format
    errors = []
    for error in exc.errors():
        # Create a clean serializable copy
        clean_error = {
            "type": error.get("type"),
            "loc": error.get("loc"),
            "msg": error.get("msg"),
            "input": error.get("input"),
        }

        # Convert ctx values to strings (handles ValueError, etc.)
        if "ctx" in error:
            clean_error["ctx"] = {k: str(v) for k, v in error["ctx"].items()}

        errors.append(clean_error)

    # Standard RESTful error format
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={"detail": errors},
    )


async def server_error_handler(
    request: Request, exc: Exception
) -> JSONResponse:  # pragma: no cover
    """
    Handle unexpected server errors.
    Returns standard RESTful error format: {detail: string}
    """
    # Log the full exception with traceback
    import sys

    print(f"\n{'='*60}", file=sys.stderr)
    print(f"ERROR on {request.url.path}:", file=sys.stderr)
    print(f"{exc}", file=sys.stderr)
    print(traceback.format_exc(), file=sys.stderr)
    print("=" * 60, file=sys.stderr)

    logger.error(f"Unhandled exception on {request.url.path}: {exc}")
    logger.error(traceback.format_exc())

    return JSONResponse(  # pragma: no cover
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={"detail": "Internal server error"},
    )
